package sw6.visualschedule.adminpanel;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;

import sw6.visualschedule.R;
import sw6.visualschedule.entities.ScheduleActivity;
import sw6.visualschedule.extendedViews.CheckBoxEntry;
import sw6.visualschedule.extendedViews.CustomEntry;
import sw6.visualschedule.extendedViews.SeperatorEntry;
import sw6.visualschedule.persistence.ScheduleActivityRepo;
import tools.BundleHelper;
import tools.DialogHelper;
import android.app.AlertDialog;
import android.app.ListActivity;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.provider.MediaStore.MediaColumns;
import android.view.View;
import android.view.WindowManager;
import android.widget.ListView;
import android.widget.Toast;

import com.commonsware.cwac.sacklist.SackOfViewsAdapter;

public class ActivityConstructor extends ListActivity {
	
	//Entry constants
	// 0 is reserved for "required" separator
	final private static int TITLE_ENTRY = 1;
	final private static int STEPS_ENTRY = 2;
	final private static int IMAGE_ENTRY = 3;
	final private static int SPONTANEOUS_ENTRY = 4;
	final private static int NOTIFICATION_ENTRY = 5;
	// 6 is reserved for "optional" separator
	final private static int DATES_ENTRY = 7;
	final private static int REPEAT_ENTRY = 8;
	
	//Object
	transient private ScheduleActivity mActivity;
	transient private int mActivityId;
	
	//Diverse
	private transient String mCameraImagePath = "";
	
	//Database
	transient private ScheduleActivityRepo mDb;
	
	//Entries
	transient private CustomEntry mTitleEntry;
	transient private CustomEntry mDateEntry; 
	transient private CustomEntry mImageEntry;
	transient private CheckBoxEntry mNotificationEntry;
	transient private CustomEntry mRepeatEntry;
	transient private CheckBoxEntry mSpontaneousEntry;
	transient private CustomEntry mStepsEntry;
	
	/**
	 * Handles back-button presses.
	 */
	@Override
	public void onBackPressed() {
		final String result = validateActivity();
		
		if ("".equalsIgnoreCase(result)) {
			super.onBackPressed();
			Toast.makeText(this, R.string.adm_ac_activity_saved, Toast.LENGTH_SHORT).show();
		} else {
			final AlertDialog.Builder builder = new AlertDialog.Builder(this);
			builder.setTitle(R.string.constructor_confirmation);
			builder.setMessage(getString(R.string.adm_ac_error_save)+"\n"+result);
			builder.setPositiveButton(getString(R.string.adm_ac_delete_quit), new OnClickListener() {
				
				@Override
				public void onClick(final DialogInterface dialog, final int which) {
					ActivityConstructor.this.superOnBackPressed();
		        	Toast.makeText(ActivityConstructor.this, R.string.adm_ac_activity_deleted, Toast.LENGTH_SHORT).show();
		        	mDb.delete(mActivity);
				}
			});
			builder.setNegativeButton(getString(R.string.adm_ac_edit_stay), null);
			builder.show();
		}
	}
	
	@Override
    public void onCreate(final Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
		setContentView(R.layout.constructor_layout_list);
		
		//Remove top bar
		this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
		
		mDb = new ScheduleActivityRepo(this);
		
		//Get Activity
		mActivityId = getIntent().getIntExtra(BundleHelper.ACTIVITY_ID, -1);
		if (savedInstanceState == null && mActivityId == -1) {
			setTitle(getString(R.string.adm_ac_activity_construct));
			mActivity = new ScheduleActivity(getString(R.string.adm_ac_activity_default_name));
			mDb.create(mActivity);
			mActivityId = mActivity.getId();
		} else if (savedInstanceState != null) {
			mActivityId = savedInstanceState.getInt(BundleHelper.ACTIVITY_ID);
			mCameraImagePath = savedInstanceState.getString(BundleHelper.CAMERA_PATH);
		}
		
		mActivity = mDb.getById(mActivityId);
	}
	
	@Override
	public void onSaveInstanceState(final Bundle savedInstanceState) {
		// Save UI state changes to the savedInstanceState.
		// This bundle will be passed to onCreate if the process is
		// killed and restarted.
		savedInstanceState.putInt(BundleHelper.ACTIVITY_ID, mActivity.getId());
		//When opening the camera intent this activity will be killed, and therefore we need to store the camera image path.
		savedInstanceState.putString(BundleHelper.CAMERA_PATH, mCameraImagePath);
		super.onSaveInstanceState(savedInstanceState);
	}
	
	/**
	 * Calls the super class' onBackPressed() method.
	 */
	public void superOnBackPressed() {
		super.onBackPressed();
	}
	
	private Boolean checkForDuplicateActivityTitles()
	{
		final ArrayList<ScheduleActivity> activities = new ArrayList<ScheduleActivity>(mDb.getAll());
		final String title = mActivity.getTitle();
		boolean result = false;
		
		for (ScheduleActivity scheduleActivity : activities) {
			if (scheduleActivity.getTitle().equals(title) && scheduleActivity.getId() != mActivityId) {
				result = true;
				break;
			}
		}
		
		return result;
	}
	
	private String getPath(final Uri uri) {
        final String[] projection = {
            MediaColumns.DATA
        };
        final Cursor cursor = managedQuery(uri, projection, null, null, null);

        final int column_index = cursor.getColumnIndexOrThrow(MediaColumns.DATA);
        cursor.moveToFirst();

        return cursor.getString(column_index);
    }
	
	private void setNotificationEntrySummary() {
		if (mActivity.useNotification()) {
			mNotificationEntry.getSummary().setText(getString(R.string.adm_ac_notification_sum_true));
		} else {
			mNotificationEntry.getSummary().setText(getString(R.string.adm_ac_notification_sum_false));
		}
	}
	
	private void setSpontaneousSummary() {
		if (mActivity.isSpontaneous()) {
			mSpontaneousEntry.getSummary().setText(getString(R.string.adm_ac_spontaneous_sum_true));
		} else {
			mSpontaneousEntry.getSummary().setText(getString(R.string.adm_ac_spontaneous_sum_false));
		}
	}
	
	private void showImageEntryDialog() {
	    final AlertDialog.Builder alert = new AlertDialog.Builder(this);
        alert.setTitle(getString(R.string.adm_ac_select_source));
        alert.setItems(new CharSequence[] {getString(R.string.adm_ac_from_storage), getString(R.string.adm_ac_from_cam)}, new DialogInterface.OnClickListener() {
            public void onClick(final DialogInterface dialog, final int item) {
                Intent internalIntent;
                switch (item) {
                case 0:// From SD card
                    internalIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                    startActivityForResult(internalIntent, BundleHelper.IMAGE_SD_RESULT);
                    break;
                case 1:// From camera
                    internalIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
                    final Date date = new Date();
                    final File photo = new File(Environment.getExternalStorageDirectory()+"/DCIM/Camera/",  "ACTIVITY"+mActivityId+"("+(date.getMonth()+1)+"-"+date.getDate()+"-"+date.getYear()+"."+date.getHours()+"."+date.getMinutes()+"."+date.getSeconds()+").jpg");
                    final Uri uri = Uri.fromFile(photo);
                    mCameraImagePath = uri.getPath();
                    
                    internalIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
                    startActivityForResult(internalIntent, BundleHelper.IMAGE_CAM_RESULT);
                    break;
                default:
                    break;
                }
            }
        });
        alert.show();
	}
	
	private String validateActivity() {
	    String result = "";
	    
	    if (mActivity.getTitle().length() <= 0) {
			result = getString(R.string.adm_ac_activity_require_title);
	    } else if (checkForDuplicateActivityTitles()) {
			result = getString(R.string.adm_ac_activity_unique);
		} else if (mActivity.getSteps().size() < 1) {
			result = getString(R.string.adm_ac_activity_missing_steps);
		} else if (mActivity.getImage() == null) {
			result = getString(R.string.adm_ac_activity_missing_image);
		}
		
		return result;
	}
	
	@Override
	protected final void onActivityResult(final int requestCode, final int resultCode, final Intent intent) {
		super.onActivityResult(requestCode, resultCode, intent);
		
		if (resultCode != RESULT_OK) {
		    return;
		}
		
		switch (requestCode) {
			case BundleHelper.IMAGE_SD_RESULT:
				mActivity.setImage(getPath(intent.getData()));
				mDb.update(mActivity);
				break;
			case BundleHelper.IMAGE_CAM_RESULT:
				/* 
				 * The intent received from the camera intent does not contain the path
				 *  to the image, just created, therefore this is store as a property on the activity.
				 */
				
				mActivity.setImage(mCameraImagePath);
				mDb.update(mActivity);
				break;
			default:
				break;
		}
	}
	
	@Override
	protected void onListItemClick(final ListView list, final View view, final int position, final long itemId) {
		Intent intent;
		
		switch (position) {
		case TITLE_ENTRY:
			DialogHelper.showTitleEntryDialog(mDb, mActivity, this, (CustomEntry)view);
			break;
		case STEPS_ENTRY:
			intent = new Intent().setClass(ActivityConstructor.this, ActivityStepList.class);
            intent.putExtra(BundleHelper.ACTIVITY_ID, mActivity.getId());
			startActivity(intent);
			break;
		case IMAGE_ENTRY:
			showImageEntryDialog();
			break;
		case SPONTANEOUS_ENTRY:
			final Boolean spon_result = !mActivity.isSpontaneous();
			((CheckBoxEntry)view).getCheckBox().setChecked(spon_result);
			mActivity.setSpontaneous(spon_result);
			mDb.update(mActivity);
			setSpontaneousSummary();
			break;
		case NOTIFICATION_ENTRY:
			final Boolean note_result = !mActivity.useNotification();
			((CheckBoxEntry)view).getCheckBox().setChecked(note_result);
			mActivity.setNotification(note_result);
			mDb.update(mActivity);
			setNotificationEntrySummary();
			break; 
		case DATES_ENTRY:
			intent = new Intent().setClass(ActivityConstructor.this, ActivityDateList.class);
            intent.putExtra(BundleHelper.ACTIVITY_ID, mActivity.getId());
			startActivity(intent);
			break; 
		case REPEAT_ENTRY:
			intent = new Intent().setClass(ActivityConstructor.this, RepeatPatternList.class);
            intent.putExtra(BundleHelper.ACTIVITY_ID, mActivity.getId());
			startActivity(intent);
			break; 
		default:
			break;
		}
	}
	
	@Override
	protected void onResume() {
		super.onResume();
		
		if (mActivity == null) {
			mActivity = mDb.getById(mActivityId);
		}
		
		final ArrayList<View> views = new ArrayList<View>();
		
		/*
		 * Initiate setting entries
		 */
		
		//Required separator
		views.add(new SeperatorEntry(this, getString(R.string.constructor_required)));
		
		//Title
		mTitleEntry = new CustomEntry(this);
		mTitleEntry.getTitle().setText(getString(R.string.adm_ac_activity_title));
		mTitleEntry.getSummary().setText(mActivity.getTitle());
		views.add(TITLE_ENTRY, mTitleEntry);
		
		//Steps
		mStepsEntry = new CustomEntry(this);
		
		mStepsEntry.getTitle().setText(getString(R.string.adm_ac_steps));
		if (mActivity.getSteps() == null) {
		    mStepsEntry.getSummary().setText(String.format(getString(R.string.adm_ac_steps_sum), 0));
		} else {
		    mStepsEntry.getSummary().setText(String.format(getString(R.string.adm_ac_steps_sum), mActivity.getSteps().size()));
		}
		
		views.add(STEPS_ENTRY, mStepsEntry);
		
		//Image
		mImageEntry = new CustomEntry(this);
		mImageEntry.getTitle().setText(getString(R.string.adm_ac_select_image));
		mImageEntry.getSummary().setText(mActivity.getImage());
		views.add(IMAGE_ENTRY, mImageEntry);
		
		//Spontaneous
		mSpontaneousEntry = new CheckBoxEntry(this);
		mSpontaneousEntry.getTitle().setText(getString(R.string.adm_ac_spontaneous));
		setSpontaneousSummary();
		
		mSpontaneousEntry.getCheckBox().setChecked(mActivity.isSpontaneous());
		views.add(SPONTANEOUS_ENTRY, mSpontaneousEntry);
		
		//Notification
		mNotificationEntry = new CheckBoxEntry(this);
		mNotificationEntry.getTitle().setText(getString(R.string.adm_ac_notification));
		setNotificationEntrySummary();
		mNotificationEntry.getCheckBox().setChecked(mActivity.useNotification());
		views.add(NOTIFICATION_ENTRY, mNotificationEntry);
		
		//Optional separator
		views.add(new SeperatorEntry(this, getString(R.string.constructor_optional)));
		
		//Date
		mDateEntry = new CustomEntry(this);
		mDateEntry.getTitle().setText(R.string.adm_ac_dates);
		if (mActivity.getDates() == null) {
		    mDateEntry.getSummary().setText("0");
		} else {
		    mDateEntry.getSummary().setText(Integer.toString(mActivity.getDates().size()));
		}	
		
		views.add(DATES_ENTRY, mDateEntry);
		
		//Repeat pattern
		mRepeatEntry = new CustomEntry(this);
		mRepeatEntry.getTitle().setText(R.string.adm_ac_repeat);
		if (mActivity.getRepeatPatterns() == null) {
		    mRepeatEntry.getSummary().setText("0");
		} else {
		    mRepeatEntry.getSummary().setText(Integer.toString(mActivity.getRepeatPatterns().size()));
		}	

		views.add(REPEAT_ENTRY, mRepeatEntry);		
		
		setListAdapter(new SackOfViewsAdapter(views));
	}

}